package com.zsr.xmall.product.config;

import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author zhousiren
 * @description
 * @date 2022/7/3 0:47
 */
//启用CacheProperties配置属性
@EnableConfigurationProperties(CacheProperties.class)
@EnableCaching
@Configuration
public class MyCacheConfig {

    /**
     *  1、引入依赖
     *          spring-boot-starter-cache
     *      2、写配置
     *          1、自动配置了那些
     *              CacheAutoConfiguration会导入 RedisCacheConfiguration
     *              自动配置好了缓存管理器，RedisCacheManager
     *          2、配置使用redis作为缓存
     *          Spring.cache.type=redis
     *
     *       4、原理 【注意是下载源码包下的java文件】
     *       CacheAutoConfiguration帮我们导入了RedisCacheConfiguration->
     *       RedisCacheConfiguration 自动配置了 RedisCacheManager ->（/org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.java:54）
     *       RedisCacheManager初始化所有的缓存 ->
     *       每个缓存决定使用什么配置
     *       ->如果redisCacheConfiguration有就用已有的，没有就用默认的
     *       ->想改缓存的配置，只需要把容器中放一个 RedisCacheConfiguration 即可
     *       ->就会应用到当前 RedisCacheManager管理所有缓存分区中
     */


    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
        //先构建出默认的配置类
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        // 当自己往IOC注入了RedisCacheConfiguration配置类时，以下参数全都失效，需要手动设置
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}
